home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / prio / _bin_heap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  4.4 KB  |  225 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _bin_heap.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. #include <LEDA/impl/bin_heap.h>
  17.  
  18. //------------------------------------------------------------------------------
  19. // bin_heap: binary heaps  
  20. //           (compressed representation with array doubling)
  21. //
  22. // S. Naeher (1993)
  23. //
  24. //------------------------------------------------------------------------------
  25.  
  26.  
  27.  
  28. #define KEY(i)   (HEAP[i]->key)
  29. #define INF(i)   (HEAP[i]->inf)
  30.  
  31.  
  32. bin_heap::bin_heap(int n)  
  33. { if (n <= 0) 
  34.      error_handler(1,string("bin_heap constructor: illegal size = %d",n));
  35.   HEAP = new bin_heap_item[n];
  36.   for(int i = 0; i < n; i++) HEAP[i] = nil;
  37.   count = 0; 
  38.   max_size = n-2;  // sometimes we use HEAP[0], HEAP[count+1] as stoppers
  39. }
  40.  
  41. bin_heap::bin_heap(const bin_heap& H)
  42. { max_size = H.max_size;
  43.   count = H.count; 
  44.   HEAP = new bin_heap_item[max_size+2];
  45.   for(int i = 1; i <= count; i++) 
  46.   { HEAP[i] = new bin_heap_elem(H.HEAP[i]->key, H.HEAP[i]->inf,i);
  47.     H.copy_key(HEAP[i]->key);
  48.     H.copy_inf(HEAP[i]->inf);
  49.   }
  50. }
  51.  
  52. bin_heap& bin_heap::operator=(const bin_heap& H)
  53. { clear();
  54.   delete HEAP;
  55.   max_size = H.max_size;
  56.   count = H.count; 
  57.   HEAP = new bin_heap_item[max_size+2];
  58.   for(int i = 1; i <= count; i++) 
  59.   { HEAP[i] = new bin_heap_elem(H.HEAP[i]->key, H.HEAP[i]->inf,i);
  60.     copy_key(HEAP[i]->key);
  61.     copy_inf(HEAP[i]->inf);
  62.   }
  63.   return *this;
  64. }
  65.  
  66. bin_heap::~bin_heap()  
  67. { clear();
  68.   delete HEAP; 
  69. }
  70.  
  71. void bin_heap::clear()
  72. { for(int i=1; i <= count; i++) 
  73.   { clear_key(KEY(i));
  74.     clear_inf(INF(i));
  75.     delete HEAP[i];
  76.    }
  77.   count = 0;
  78. }
  79.  
  80.  
  81. void bin_heap::rise(int pos, bin_heap_item it)
  82.   HEAP[0] = it;  // use "it" as stopper
  83.  
  84.   register int  pi = pos/2;                     // parent index
  85.   register bin_heap_item parent = HEAP[pi];     // parent node
  86.  
  87.  
  88.   if (int_type())
  89.      while(parent->key > it->key)
  90.      { HEAP[pos] = parent;
  91.        parent->index = pos;
  92.        pos = pi;
  93.        pi >>= 1;
  94.        parent = HEAP[pi];
  95.       }
  96.   else
  97.      while (cmp(parent->key,it->key) > 0)
  98.      { HEAP[pos] = parent;
  99.        parent->index = pos;
  100.        pos = pi;
  101.        pi >>= 1;
  102.        parent = HEAP[pi];
  103.       }
  104.  
  105.   HEAP[pos] = it;
  106.   it->index = pos;
  107. }
  108.  
  109.  
  110. void bin_heap::sink(int pos, bin_heap_item it)
  111.   register int ci = 2*pos;       // child index
  112.  
  113.   register bin_heap_item child;  // child node
  114.  
  115.  
  116.   HEAP[count+1] = HEAP[count];   // stopper
  117.  
  118.   if (int_type())
  119.      while (ci <= count)
  120.      { child = HEAP[ci];
  121.        if (KEY(ci+1) < child->key) child = HEAP[++ci];
  122.        if (it->key > child->key) 
  123.        { HEAP[pos] = child;
  124.          child->index = pos;
  125.          pos = ci;
  126.          ci <<= 1;
  127.         }
  128.        else break;
  129.       }
  130.   else
  131.      while (ci <= count)
  132.      { child = HEAP[ci];
  133.        if (ci < count && cmp(KEY(ci+1),child->key) < 0) child = HEAP[++ci];
  134.        if (cmp(it->key,child->key)>0) 
  135.        { HEAP[pos] = child;
  136.          child->index = pos;
  137.          pos = ci;
  138.          ci <<= 1;
  139.         }
  140.        else break;
  141.       }
  142.  
  143.   HEAP[pos] =it;
  144.   it->index = pos;
  145. }
  146.  
  147.  
  148.  
  149. void bin_heap::decrease_key(bin_heap_item it, GenPtr k)
  150. { if (cmp(it->key,k)<0) 
  151.        error_handler(1,"bin_heap: key too large in decrease_key");
  152.   clear_key(it->key);
  153.   copy_key(k);
  154.   it->key = k;
  155.   rise(it->index, it);
  156. }
  157.  
  158.  
  159. bin_heap_item bin_heap::insert(GenPtr k, GenPtr i) 
  160.   bin_heap_item* H;
  161.  
  162.   if (count == max_size)  // resize
  163.   { // max_size *= 2;     // double array
  164.     max_size += 1024;
  165.     H = new bin_heap_item[max_size+2];
  166.     for(int i=1; i<= count; i++) H[i] = HEAP[i];
  167.     delete HEAP;
  168.     HEAP = H;
  169.    }
  170.  
  171.   count++;
  172.   copy_key(k);
  173.   copy_inf(i);
  174.   bin_heap_item it = new bin_heap_elem(k,i,count);
  175.   rise(count,it);
  176.  
  177.   return it;
  178. }
  179.  
  180.  
  181.  
  182.  
  183. void bin_heap::del_item(bin_heap_item it)
  184. { bin_heap_item p = HEAP[count];
  185.  
  186.   HEAP[count] = nil;
  187.  
  188.   count--;
  189.  
  190.   if (it != p)
  191.   { if (cmp(p->key,it->key) > 0)
  192.        sink(it->index, p);
  193.     else
  194.        rise(it->index, p);
  195.    }
  196.  
  197.   clear_key(it->key);
  198.   clear_inf(it->inf);
  199.  
  200.   delete it;
  201. }
  202.  
  203.  
  204. void bin_heap::change_inf(bin_heap_item it, GenPtr i) 
  205. { clear_inf(it->inf);
  206.   copy_inf(i);
  207.   it->inf = i; 
  208.  }
  209.  
  210. void bin_heap::print()
  211. { cout << "size = " << count << endl;
  212.   for(int i=1;i<=count;i++) 
  213.   { print_key(KEY(i));
  214.     cout << "-";
  215.     print_inf(INF(i));
  216.     cout << "  ";
  217.    }
  218.   newline;
  219. }
  220.  
  221.